/**
 * 支付工具模块
 * 提供微信支付相关的工具函数和状态管理
 */

import request from '@/api/request.js';

// 支付状态枚举
export const PaymentStatus = {
  IDLE: 'idle',
  LOADING: 'loading',
  AUTHORIZING: 'authorizing',
  PROCESSING: 'processing',
  SUCCESS: 'success',
  FAILED: 'failed',
  CANCELLED: 'cancelled'
};

// 支付错误类型
export const PaymentError = {
  NOT_IN_WECHAT: 'NOT_IN_WECHAT',
  MISSING_PARAMS: 'MISSING_PARAMS',
  AUTH_FAILED: 'AUTH_FAILED',
  CREATE_ORDER_FAILED: 'CREATE_ORDER_FAILED',
  PAY_FAILED: 'PAY_FAILED',
  NETWORK_ERROR: 'NETWORK_ERROR'
};

/**
 * 检查是否在微信环境中
 * @returns {boolean}
 */
export function isInWechat() {
  const ua = navigator.userAgent.toLowerCase();
  return ua.indexOf('micromessenger') !== -1 && typeof WeixinJSBridge !== 'undefined';
}

/**
 * 检查微信支付环境
 * @returns {Object} 检查结果
 */
export function checkWechatPayEnvironment() {
  const result = {
    isValid: false,
    hasWeixinJSBridge: typeof WeixinJSBridge !== 'undefined',
    hasWxChoosePay: typeof wx !== 'undefined' && typeof wx.chooseWXPay === 'function',
    isInWechat: isInWechat(),
    error: null
  };

  if (!result.isInWechat) {
    result.error = PaymentError.NOT_IN_WECHAT;
  } else if (!result.hasWeixinJSBridge) {
    result.error = 'WeixinJSBridge not available';
  } else {
    result.isValid = true;
  }

  return result;
}

/**
 * 解析URL参数（支持hash路由）
 * @param {string} url - 要解析的URL
 * @returns {Object} 解析出的参数对象
 */
export function parseUrlParams(url = window.location.href) {
  const params = {};
  try {
    // 解析查询参数
    const urlObj = new URL(url);
    urlObj.searchParams.forEach((value, key) => {
      params[key] = value;
    });

    // 解析hash中的参数
    if (urlObj.hash) {
      const hashParts = urlObj.hash.split('?');
      if (hashParts.length > 1) {
        const queryPart = hashParts[1].split('#')[0];
        const hashParams = new URLSearchParams(queryPart);
        hashParams.forEach((value, key) => {
          if (!params[key]) { // 优先使用查询参数
            params[key] = value;
          }
        });
      }
    }
  } catch (error) {
    console.error('解析URL参数失败:', error);
  }

  return params;
}

/**
 * 检测是否为微信授权回调
 * @param {Object} options - 页面参数
 * @returns {Object} 检测结果
 */
export function detectWechatAuthCallback(options = {}) {
  const urlParams = parseUrlParams();
  const referrer = document.referrer || '';
  const currentUrl = window.location.href;
  
  // 从多个来源获取授权参数
  let authCode = options.code || urlParams.code;
  let authState = options.state || urlParams.state;
  
  // 检查是否来自微信授权页面
  const isFromWechatAuth = referrer.includes('open.weixin.qq.com') || 
                          referrer.includes('oauth') || 
                          referrer.includes('wx.qq.com');
  
  // 检查URL中是否包含微信授权标识
  const hasWechatRedirect = currentUrl.includes('wechat_redirect');
  
  // 获取合同编号
  const contractNumber = options.contractNumber || urlParams.contractNumber;
  
  // 如果从URL中获取不到有效的授权码，尝试从临时存储中恢复
  if ((!authCode || authCode.length <= 10) && contractNumber) {
    console.log('URL中未找到有效授权码，尝试从临时存储恢复');
    const tempAuthKey = `temp_auth_${contractNumber}`;
    try {
      const tempAuthData = JSON.parse(sessionStorage.getItem(tempAuthKey) || '{}');
      if (tempAuthData.authCode && tempAuthData.authState && 
          tempAuthData.authCode.length > 10 && 
          (Date.now() - tempAuthData.timestamp) < 30000) { // 30秒内有效
        authCode = tempAuthData.authCode;
        authState = tempAuthData.authState;
        console.log('从临时存储恢复授权信息成功');
      }
    } catch (e) {
      console.warn('从临时存储恢复授权信息失败:', e);
    }
  }
  
  const result = {
    hasAuthCallback: false,
    authCode,
    authState,
    isFromWechatAuth,
    hasWechatRedirect,
    contractNumber
  };

  // 更严格的授权回调判断逻辑
  // 必须同时满足以下条件之一：
  // 1. 有完整的授权参数（code和state）
  // 2. 来自微信授权页面且有合同编号且有授权码
  // 3. URL包含wechat_redirect且有授权码
  // 同时排除已处理过的授权回调
  result.hasAuthCallback = (authCode && authCode.length > 10 && authState) || 
                          (isFromWechatAuth && result.contractNumber && authCode && authCode.length > 10) ||
                          (hasWechatRedirect && authCode && authCode.length > 10);

  // 检查是否已经处理过，这里只检查sessionStorage，避免localStorage中的旧标记阻止新的有效授权
  if (result.hasAuthCallback && authCode) {
    const processedKey = `auth_processed_${result.contractNumber || 'unknown'}_${authCode}`;
    if (sessionStorage.getItem(processedKey)) {
      console.log('授权回调已处理过，跳过重复处理');
      result.hasAuthCallback = false;
      result.isAlreadyProcessed = true;
    }
    // 注意：不在这里标记为已处理，而是在实际处理完成后标记
  }
  
  // 对于授权码格式无效的情况，提前过滤
  if (authCode && authCode.length <= 10) {
    console.log('授权码格式无效，不视为授权回调');
    result.hasAuthCallback = false;
  }

  console.log('授权回调检测结果:', result);
  return result;
}

/**
 * 缓存支付参数
 * @param {string} contractNumber - 合同编号
 * @param {Object} paymentParams - 支付参数
 */
export function cachePaymentParams(contractNumber, paymentParams) {
  const cacheKey = `wechat_pay_params_${contractNumber}`;
  try {
    uni.setStorageSync(cacheKey, {
      wechat_pay_params: paymentParams.wechat_pay_params,
      payment_type: paymentParams.payment_type,
      timestamp: Date.now()
    });
  } catch (error) {
    console.error('缓存支付参数失败:', error);
  }
}

/**
 * 获取缓存的支付参数
 * @param {string} contractNumber - 合同编号
 * @returns {Object|null} 缓存的支付参数
 */
export function getCachedPaymentParams(contractNumber) {
  const cacheKey = `wechat_pay_params_${contractNumber}`;
  try {
    const cached = uni.getStorageSync(cacheKey);
    if (cached && cached.wechat_pay_params) {
      // 检查缓存是否过期（30分钟）
      const isExpired = Date.now() - (cached.timestamp || 0) > 30 * 60 * 1000;
      if (isExpired) {
        uni.removeStorageSync(cacheKey);
        return null;
      }
      return cached;
    }
  } catch (error) {
    console.error('获取缓存支付参数失败:', error);
  }
  return null;
}

/**
 * 清除缓存的支付参数
 * @param {string} contractNumber - 合同编号
 */
export function clearCachedPaymentParams(contractNumber) {
  const cacheKey = `wechat_pay_params_${contractNumber}`;
  try {
    uni.removeStorageSync(cacheKey);
  } catch (error) {
    console.error('清除缓存支付参数失败:', error);
  }
}

/**
 * 调用微信支付
 * @param {Object} wechatPayParams - 微信支付参数
 * @param {string} paymentType - 支付类型
 * @returns {Promise} 支付结果
 */
export function callWechatPay(wechatPayParams, paymentType = 'JSAPI') {
  return new Promise((resolve, reject) => {
    console.log('调用微信支付:', { paymentType });
    console.log('支付参数详细信息:', {
      hasTimeStamp: !!wechatPayParams.timeStamp,
      hasNonceStr: !!wechatPayParams.nonceStr,
      hasPackage: !!wechatPayParams.package,
      hasSignType: !!wechatPayParams.signType,
      hasPaySign: !!wechatPayParams.paySign,
      hasAppId: !!wechatPayParams.appId
    });

    // 检查支付环境
    const envCheck = checkWechatPayEnvironment();
    if (!envCheck.isValid) {
      const error = new Error(envCheck.error === PaymentError.NOT_IN_WECHAT ? '请在微信中打开' : '微信支付环境不可用');
      error.code = envCheck.error;
      reject(error);
      return;
    }

    // 检查支付参数完整性
    if (!wechatPayParams || !wechatPayParams.timeStamp || !wechatPayParams.nonceStr || 
        !wechatPayParams.package || !wechatPayParams.signType || !wechatPayParams.paySign) {
      const missingParams = [];
      if (!wechatPayParams.timeStamp) missingParams.push('timeStamp');
      if (!wechatPayParams.nonceStr) missingParams.push('nonceStr');
      if (!wechatPayParams.package) missingParams.push('package');
      if (!wechatPayParams.signType) missingParams.push('signType');
      if (!wechatPayParams.paySign) missingParams.push('paySign');
      
      const error = new Error(`支付参数不完整，缺少: ${missingParams.join(', ')}`);
      error.code = 'INCOMPLETE_PAYMENT_PARAMS';
      reject(error);
      return;
    }

    if (paymentType === 'JSAPI') {
      // 准备标准化的支付参数（确保参数名与微信SDK要求一致）
      const standardizedParams = {
        timeStamp: wechatPayParams.timeStamp.toString(), // 确保是字符串
        nonceStr: wechatPayParams.nonceStr,
        package: wechatPayParams.package,
        signType: wechatPayParams.signType || 'MD5',
        paySign: wechatPayParams.paySign,
        appId: wechatPayParams.appId // 某些环境可能需要appId
      };
      
      console.log('标准化后的支付参数:', standardizedParams);

      // 优先使用wx.chooseWXPay
      if (typeof wx !== 'undefined' && typeof wx.chooseWXPay === 'function') {
        console.log('使用wx.chooseWXPay方法');
        wx.chooseWXPay({
          timestamp: standardizedParams.timeStamp, // 注意：这里使用小写的timestamp
          nonceStr: standardizedParams.nonceStr,
          package: standardizedParams.package,
          signType: standardizedParams.signType,
          paySign: standardizedParams.paySign,
          appId: standardizedParams.appId, // 添加appId以增强兼容性
          success: (res) => {
            console.log('微信支付成功:', res);
            resolve({ status: PaymentStatus.SUCCESS, data: res });
          },
          cancel: (res) => {
            console.log('用户取消支付:', res);
            const error = new Error('支付已取消');
            error.code = PaymentStatus.CANCELLED;
            reject(error);
          },
          fail: (res) => {
            console.error('微信支付失败:', res);
            const error = new Error(`支付失败: ${res.errMsg || '未知错误'}`);
            error.code = PaymentStatus.FAILED;
            error.details = res;
            reject(error);
          }
        });
      } else if (typeof WeixinJSBridge !== 'undefined') {
        // 使用WeixinJSBridge作为备选方案
        console.log('使用WeixinJSBridge备选方案');
        WeixinJSBridge.invoke('getBrandWCPayRequest', standardizedParams, (res) => {
          console.log('WeixinJSBridge支付回调:', res);
          if (res.err_msg === 'get_brand_wcpay_request:ok') {
            resolve({ status: PaymentStatus.SUCCESS, data: res });
          } else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
            const error = new Error('支付已取消');
            error.code = PaymentStatus.CANCELLED;
            reject(error);
          } else {
            const error = new Error(`支付失败: ${res.err_msg || '未知错误'}`);
            error.code = PaymentStatus.FAILED;
            error.details = res;
            reject(error);
          }
        });
      } else {
        // 两种支付方式都不可用
        console.error('微信支付接口不可用');
        const error = new Error('微信支付接口不可用，请更新微信版本');
        error.code = 'WECHAT_PAY_INTERFACE_UNAVAILABLE';
        reject(error);
      }
    } else {
      const error = new Error(`不支持的支付类型: ${paymentType}`);
      error.code = 'UNSUPPORTED_PAYMENT_TYPE';
      reject(error);
    }
  });
}

/**
 * 获取微信授权
 * @param {string} contractNumber - 合同编号
 * @returns {Promise} 授权结果
 */
export function getWechatAuth(contractNumber) {
  return new Promise((resolve, reject) => {
    if (!contractNumber) {
      reject(new Error('合同编号不能为空'));
      return;
    }
    request.post('/api/payments/wechat/auth', {
      contractNumber: contractNumber
    }).then(res => {
      if (res && res.data && res.data.authUrl) {
        resolve(res.data);
      } else {
        reject(new Error('获取授权URL失败'));
      }
    }).catch(err => {
      console.error('获取微信授权失败:', err);
      reject(err);
    });
  });
}

/**
 * 创建支付订单
 * @param {Object} params - 支付参数
 * @returns {Promise} 创建结果
 */
export function createPaymentOrder(params) {
  console.log('创建支付订单参数:', params);
  const { contractId, amount, contractNumber, paymentMethod = 'wechat', ...otherParams } = params;
  
  if (!contractId || !amount || !contractNumber) {
    return Promise.reject(new Error('支付参数不完整'));
  }

  return request.post('/api/payments/create', {
    contractId,
    amount,
    contractNumber,
    paymentMethod,
    ...otherParams
  }).then(res => {
    if (res && res.code === 200) {
      return res.data;
    } else {
      throw new Error(res.message || '创建支付订单失败');
    }
  });
}

/**
 * 统一的错误处理
 * @param {Error} error - 错误对象
 * @param {string} defaultMessage - 默认错误消息
 */
export function handlePaymentError(error, defaultMessage = '操作失败') {
  console.error('支付错误:', error);
  
  let message = defaultMessage;
  
  if (error.code === PaymentError.NOT_IN_WECHAT) {
    message = '请在微信中打开';
  } else if (error.code === PaymentStatus.CANCELLED) {
    message = '支付已取消';
  } else if (error.code === PaymentStatus.FAILED) {
    message = '支付失败';
  } else if (error.message) {
    message = error.message;
  }

  uni.showToast({
    title: message,
    icon: error.code === PaymentStatus.CANCELLED ? 'none' : 'none',
    duration: 2000
  });
}

/**
 * 显示加载状态
 * @param {string} title - 加载提示文字
 */
export function showPaymentLoading(title = '处理中...') {
  uni.showLoading({
    title,
    mask: true
  });
}

/**
 * 隐藏加载状态
 */
export function hidePaymentLoading() {
  uni.hideLoading();
}

/**
 * 显示支付成功提示
 * @param {Function} callback - 成功后的回调函数
 */
export function showPaymentSuccess(callback) {
  uni.showToast({
    title: '支付成功',
    icon: 'success',
    duration: 2000
  });
  
  if (callback && typeof callback === 'function') {
    setTimeout(callback, 2000);
  }
}